package jp.co.iris_ltd.irisphotoeditor;

import java.io.File;
import java.io.FileOutputStream;
import java.text.DecimalFormat;

import jp.co.iris_ltd.irisphotoeditor.util.IrisPhotoEditorDialogBuilder;
import jp.co.iris_ltd.irisphotoeditor.widget.CanvasImageView;
import jp.co.iris_ltd.irisphotoeditor.widget.CanvasImageView.CanvaMode;
import jp.co.iris_ltd.irisphotoeditor.widget.CanvasImageView.ToolMode;
import jp.co.iris_ltd.twitter.TwitterManager;
import jp.co.iris_ltd.twitter.TwitterManager.TwitterManagerListner;

import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.PopupWindow;
import android.widget.Toast;

public class IrisPhotoEditorActivity extends Activity implements View.OnClickListener, TwitterManagerListner {
    private static final String TAG = "IrisPhotoEditorActivity";

    private Handler mHandler;
    private IrisPhotoEditorApplication mAppContext;
    private CanvasImageView mCanvasImageView;
    private Canvas mCanvas;
    private Bitmap mBitmap;
    private int mWIndowWidth;
    private int mWindowHeight;
    private PopupWindow mPentoolSelector;
    private PopupWindow mPopupWindow;
    private TwitterManager mTwitterManager;
    private String mNewestImagePath;
    private AlertDialog mProgressDialog;

    /* Getter & Setter */
    public TwitterManager getTwitterManager() {
        return mTwitterManager;
    }

    public String getNewestImagePath() {
        return mNewestImagePath;
    }

    public CanvasImageView getCanvasImageView() {
        return mCanvasImageView;
    }

    public Bitmap getCanvasBitmap() {
        return mBitmap;
    }

    /* Activity methods */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAppContext = (IrisPhotoEditorApplication) getApplicationContext();
        setContentView(R.layout.activity_iris_photo_editor);

        mHandler = new Handler();

        findViews();
        setListner();

        Resources res = getResources();
        String consumerKey = res.getString(R.string.twitter_costomer_key);
        String consumerKeySecret = res.getString(R.string.twitter_costomer_key_secret);
        mTwitterManager = new TwitterManager(this, consumerKey, consumerKeySecret);

        mHandler.postDelayed(new Runnable() {

            @Override
            public void run() {
                mWIndowWidth = mCanvasImageView.getWidth();
                mWindowHeight = mCanvasImageView.getHeight();
                mBitmap = ((IrisPhotoEditorApplication) getApplicationContext()).getBaseBitmap();
                Paint i = PentoolPalette.getDefaultInlinePaint();
                Paint o = PentoolPalette.getDefaultOutlinePaint();
                if (mBitmap == null) {
                    Log.d(TAG, "Bipmap is null!");
                    mBitmap = Bitmap.createBitmap(mWIndowWidth, mWindowHeight, Bitmap.Config.ARGB_8888);
                    mCanvas = new Canvas(mBitmap);

                    mCanvasImageView.setPaint(i, o);
                    mCanvas.drawColor(Color.WHITE);
                    mCanvasImageView.setup(mBitmap, true);

                } else {
                    mCanvasImageView.setPaint(i, o);

                    mCanvasImageView.setup(mBitmap, true);
                }
            }
        }, 300);

    }

    private void findViews() {
        mCanvasImageView = (CanvasImageView) findViewById(R.id.imgCanvas);
    }

    private void setListner() {
        mPentoolSelector = createPentoolSelector();

        findViewById(R.id.btnMove).setOnClickListener(this);
        findViewById(R.id.btnPen).setOnClickListener(this);
        findViewById(R.id.btnStamp).setOnClickListener(this);
        findViewById(R.id.btnFilter).setOnClickListener(this);
        findViewById(R.id.btnFrame).setOnClickListener(this);
        findViewById(R.id.btnUndo).setOnClickListener(this);
        findViewById(R.id.btnRedo).setOnClickListener(this);
        findViewById(R.id.btnOpen).setOnClickListener(this);
        findViewById(R.id.btnSave).setOnClickListener(this);
        findViewById(R.id.btnTwitter).setOnClickListener(this);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (mPopupWindow != null && mPopupWindow.isShowing()) {
                mPopupWindow.dismiss();
                return true;
            } else {
                showConfirmNewDialog();
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (data.getIntExtra(FilePickerActivity.ITEM_TYPE_KEY, FilePickerActivity.ITEM_TYPE_PHOTO)) {
            case FilePickerActivity.ITEM_TYPE_PHOTO:
                String filePath = data.getStringExtra(FilePickerActivity.FILE_PATH_KEY);
                mBitmap = loadImage(filePath);
                if (mBitmap != null) {
                    mCanvas = new Canvas(mBitmap);
                    mCanvasImageView.setImageBitmap(mBitmap);
                    mAppContext.setHistory(mCanvasImageView.resetHistory());
                } else {
                    showToastMessage(R.string.failed_to_decode);
                }
                break;
            case FilePickerActivity.ITEM_TYPE_STAMP:
                mCanvasImageView.setCanvasMode(CanvaMode.Draw);
                int position = data.getIntExtra(FilePickerActivity.RESOUSE_NUMBER_KEY, -1);

                if (position != -1) {
                    Resources res = getResources();
                    TypedArray stamps = res.obtainTypedArray(R.array.stamp_list);
                    Drawable stampdDrawable = stamps.getDrawable(position);

                    if (stampdDrawable != null) {
                        mCanvasImageView.setArtToolDrawable(stampdDrawable);
                        mCanvasImageView.setArtToolMode(ToolMode.Stamp);
                        mCanvasImageView.remakeArtTool();
                    }
                    stamps.recycle();
                }
                break;
            case FilePickerActivity.ITEM_TYPE_RECTANGLE_FRAME:
                // TODO:
                break;
            case FilePickerActivity.ITEM_TYPE_CORNER_FRAME:
                // TODO:
                break;
            default:
                break;
            }
        }

    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        mTwitterManager.setKeyToken(intent.getData());
    }

   @Override
    public void finish() {
        mAppContext.init();
        super.finish();
    }

    /* Implements methods */
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btnMove:
            mCanvasImageView.setCanvasMode(CanvaMode.Move);
            break;
        case R.id.btnPen:
            mPentoolSelector.showAsDropDown(v);
            break;
        case R.id.btnStamp:
            showStampList();
            break;
        case R.id.btnFilter:
            showEffectListDialog();
            break;
        case R.id.btnFrame:
            showToastMessage("Has not been programmed");
            break;
        case R.id.btnUndo:
            mCanvasImageView.undoCanvas();
            break;
        case R.id.btnRedo:
            mCanvasImageView.redoCanvas();
            break;
        case R.id.btnOpen:
            showPhotoList();
            break;
        case R.id.btnSave:
            showSaveDialog();
            break;
        case R.id.btnTwitter:
            uploadImageForTwitter();
            break;
        default:
            showToastMessage("Has not been programmed");
            break;
        }
    }

    @Override
    public void onStartOAuth() {
        showProgressDialog();
    }

    @Override
    public void onFinishOAuth() {
        dismissProgressDialog();

    }

    @Override
    public void onStartGetToken() {
        showProgressDialog();
    }

    @Override
    public void onFinishGetToken() {
        dismissProgressDialog();
    }

    /* Show & Dismiss methods */
    public void showPhotoList() {
        Intent intent = new Intent(this, FilePickerActivity.class);
        intent.putExtra(FilePickerActivity.ITEM_TYPE_KEY, FilePickerActivity.ITEM_TYPE_PHOTO);
        startActivityForResult(intent, 0);
    }

    public void showStampList() {
        Intent intent = new Intent(this, FilePickerActivity.class);
        intent.putExtra(FilePickerActivity.ITEM_TYPE_KEY, FilePickerActivity.ITEM_TYPE_STAMP);
        startActivityForResult(intent, 0);
    }

    public void showRectangleFrame() {
        // TODO: show rectangle frame.
    }

    public void showCornerFrame() {
        // TODO: show corner frame.
    }

    public void showProgressDialog() {
        mProgressDialog = IrisPhotoEditorDialogBuilder.makeTwitterProgress(this).show();
    }

    public void dismissProgressDialog() {
        if (mProgressDialog != null && mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }
    }

    public void showSaveFileForTweetDialog() {
        IrisPhotoEditorDialogBuilder.makeSaveFileForTweetDialog(this).show();
    }

    public void showTweetDialog() {
        IrisPhotoEditorDialogBuilder.makeTweetDialog(this).show();
    }

    public void showToastMessage(String str) {
        Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
    }

    public void showToastMessage(int stringId) {
        showToastMessage(getResources().getString(stringId));
    }

    private void showEffectListDialog() {
        IrisPhotoEditorDialogBuilder.makeEffectListDialog(this).show();
    }

    public void showSaveDialog() {
        IrisPhotoEditorDialogBuilder.makeSaveDialog(this).show();
    }

    private void showConfirmNewDialog() {
        IrisPhotoEditorDialogBuilder.makeConfirmNewDialog(this).show();
    }

    private PopupWindow createPentoolSelector() {
        mPopupWindow = new PopupWindow(this);
        mPopupWindow.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        ViewGroup layout = (ViewGroup) getLayoutInflater().inflate(R.layout.pen_selector, null);
        final PentoolPalette palette = (PentoolPalette) layout.findViewById(R.id.pentoolParette);
        palette.init();
        View.OnClickListener listener = new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                switch (v.getId()) {
                case R.id.btnPenOk:
                    mCanvasImageView.setCanvasMode(CanvaMode.Draw);
                    Paint in = palette.getInlinePaint();
                    Paint out = palette.getOutlinePaint();

                    mCanvasImageView.setPaint(in, out);
                    mCanvasImageView.setArtToolMode(ToolMode.Pen);
                    mCanvasImageView.remakeArtTool();
                    break;
                default:
                    break;
                }
                mPopupWindow.dismiss();
            }
        };
        layout.findViewById(R.id.btnPenCancel).setOnClickListener(listener);
        layout.findViewById(R.id.btnPenOk).setOnClickListener(listener);
        mPopupWindow.setContentView(layout);

        return mPopupWindow;
    }

    private void uploadImageForTwitter() {
        if (!mTwitterManager.isOAuthed()) {
            mTwitterManager.doOAuth();
        } else if (mNewestImagePath == null || mNewestImagePath == "") {
            showSaveFileForTweetDialog();
        } else {
            showTweetDialog();
        }
    }

    private boolean writeImage(File file) {
        try {
            FileOutputStream fo = new FileOutputStream(file);
            mCanvasImageView.getBitmap().compress(CompressFormat.PNG, 100, fo);
            fo.flush();
            fo.close();

        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
            return false;
        }
        return true;
    }

    private boolean externalMediaChecker() {
        boolean result = false;
        String status = Environment.getExternalStorageState();
        if (status.equals(Environment.MEDIA_MOUNTED)) {
            result = true;
        }
        return result;
    }

    public void save(String name) {
        if (externalMediaChecker()) {
            Resources res = getResources();

            String folderName = res.getString(R.string.photo_save_folder);
            String path = Environment.getExternalStorageDirectory() + folderName;

            File outDir = new File(path);
            if (!outDir.exists()) {
                outDir.mkdir();
                Log.i(TAG, "Dir make");
            }
            String photoExtension = res.getString(R.string.photo_extension);
            File file = new File(path + name + photoExtension);
            if (name == "" || file.exists()) {
                DecimalFormat form = new DecimalFormat("0000");
                int imageNumber = 1;
                do {
                    file = new File(path + name + "_" + form.format(imageNumber) + photoExtension);
                    imageNumber++;
                } while (file.exists());
            }
            if (writeImage(file)) {
                String _url = "file://" + Environment.getExternalStorageDirectory();
                Uri uri = Uri.parse(_url);
                sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, uri));

                mNewestImagePath = file.getPath();
                String message = getResources().getString(R.string.toast_saving_success_message, file.getPath());
                showToastMessage(message);
            } else {
                showToastMessage(R.string.toast_saving_failed_message);
            }
        }
    }

    private Bitmap loadImage(String path) {
        boolean landscape = false;
        Bitmap bm;

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        int oh = options.outHeight;
        int ow = options.outWidth;

        if (ow > oh) {
            landscape = true;
            oh = options.outWidth;
            ow = options.outHeight;
        }

        options.inJustDecodeBounds = false;
        options.inSampleSize = Math.max(ow / mWIndowWidth, oh / mWindowHeight);
        bm = BitmapFactory.decodeFile(path, options);


        if (landscape) {
            Matrix matrix = new Matrix();
            matrix.setRotate(90.0f);
            bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, false);
        }
        try {
            if(bm.isMutable() != true) {
                bm = bm.copy(Config.ARGB_8888, true);
            }
//            bm = Bitmap.createScaledBitmap(bm, (int) (mWIndowWidth), (int) (mWindowHeight * ( oh /  ow)), false);
//            Bitmap offBitmap = Bitmap.createBitmap(mWIndowWidth, mWindowHeight, Bitmap.Config.ARGB_8888);
//            Canvas offCanvas = new Canvas(offBitmap);
//            offCanvas.drawBitmap(bm, 0, (mWindowHeight - bm.getHeight()) / 2, null);
//            bm = offBitmap;

        } catch (NullPointerException e) {
            showToastMessage(R.string.failed_to_decode);
            bm = null;
        } catch (OutOfMemoryError e) {
            showToastMessage(R.string.toast_image_loading_failed);
            bm = null;
        }

        return bm;
    }

}
